#include "IMReceiver.h"
#include "../Biz/MsgBusParam/IMMessageParam.h"
#include "../Biz/MsgBusParam/IMFileTransferParam.h"
#include "../Core/xparam.hpp"
#include "../Biz/WWBizUtility.h"
#include "../Core/SimpleLogger.h"
#include "../Biz/FileTransfer/BaseFileTransfer.h"
#include "../Biz/FileTransfer/p2pbase.h"
#include "../Core/MsgHandlerMgr.h"

#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>

using namespace wwbiz;
using namespace NetMsgBus;
using namespace core;

static LoggerCategory g_log("IMReceiver");

void ForceQuit()
{
    MsgHandlerMgr::DropAllInstance();
    NetMsgBusDisConnect();
    DestroyMsgBus();
    threadpool::destroy_thread_pool();
    printf("CmdIMReceiverMain Quit!\n");
}

IMReceiver::IMReceiver()
{
    m_running = true;
    m_healthtimerid = -1;
    m_is_inloginsession = false;
    m_exportfilepath = "";
}
void IMReceiver::InitMsgHandler()
{
    //AddHandler("im.biz.updategroupinfo.finished", &IMReceiver::OnUpdateGroupFinished, 0);
    //AddHandler("im.biz.updatecontactinfo.finished", &IMReceiver::OnUpdateContactFinished, 0);
    //AddHandler("im.biz.building.usergrouprelationship.finished", &IMReceiver::OnBuildingU2GRelationFinished, 0);
    AddHandler("im.frontend.cmd.dologin", &IMReceiver::OnDoLogin, 0);
    AddHandler("im.frontend.cmd.dosendtextmsg", &IMReceiver::OnDoSendTextMessage, 0);
    AddHandler("im.frontend.cmd.dologout", &IMReceiver::OnDoLogout, 0);
    AddHandler("im.frontend.cmd.dorelogin", &IMReceiver::OnDoReLogin, 0);
    AddHandler("im.frontend.cmd.doquit", &IMReceiver::OnDoQuit, 0);
    AddHandler("im.frontend.cmd.doverifyuser", &IMReceiver::OnDoVerifyUser, 0);
    AddHandler("im.frontend.cmd.dosendfile", &IMReceiver::OnDoSendFile, 0);
    AddHandler("im.frontend.cmd.doexportbinmsgs", &IMReceiver::OnDoExportBinMsgs, 0);
    AddHandler("im.frontend.cmd.filetransfer.donotifyotherside", &IMReceiver::OnDoNotifyOtherSide, 0);

    AddHandler("im.frontend.imreceiver.login.logout" , &IMReceiver::OnLogout, 0); 
    AddHandler("im.frontend.imreceiver.login.loginerror" , &IMReceiver::OnLogout, 0);
    AddHandler("im.frontend.imreceiver.login.kicked" , &IMReceiver::OnLogout, 0);
    AddHandler("im.frontend.imreceiver.fatalerror" , &IMReceiver::OnLogout, 0);
    AddHandler("im.frontend.imreceiver.login.neterr" , &IMReceiver::OnLogout, 0); 

    AddHandler("im.frontend.imreceiver.textmsg", &IMReceiver::OnTextMsg, 0);
    AddHandler("im.frontend.imreceiver.reqquit", &IMReceiver::OnReqQuit, 0);
    AddHandler("im.frontend.group2contacts.infoready", &IMReceiver::OnIMContactsReady, 0);
    AddHandler("im.frontend.imreceiver.addcontact.addedbyother", &IMReceiver::OnIMAddContact, 0);
    AddHandler("im.frontend.imreceiver.subscription_message", &IMReceiver::OnIMSubscriptionMsg, 0);
    AddHandler("im.frontend.imreceiver.userverifyinfo.update", &IMReceiver::OnIMVerifyUserUpdate, 0);
    AddHandler("im.frontend.imreceiver.needauthcode", &IMReceiver::OnIMNeedAuthCode, 0);
    AddHandler("im.frontend.imreceiver.doexportbinmsgs.rsp", &IMReceiver::OnIMRspExportBinMsgs, 0);
    //AddHandler("im.frontend.imreceiver.checkauthcode.ok", &IMReceiver::OnIMAuthCodeOK, 0);
    //AddHandler("im.frontend.imreceiver.checkauthcode.failed", &IMReceiver::OnIMAuthCodeFailed, 0);
    AddHandler("im.frontend.imreceiver.login.failed", &IMReceiver::OnIMLoginFailed, 0);
    AddHandler("im.frontend.imreceiver.login.ok", &IMReceiver::OnIMLoginOK, 0);

    // filetransfer messages
    AddHandler("im.frontend.imreceiver.filetransfer.notify", &IMReceiver::OnIMFileTransferNotify, 0);
    AddHandler("im.frontend.imreceiver.pictransfer.finished", &IMReceiver::OnIMPicTransferFinished, 0);

    AddHandler("netmsgbus.server.getclient.error", &IMReceiver::OnIMMainError, 0);
    AddHandler("netmsgbus.client.connectreceiver.failed", &IMReceiver::OnIMMainError, 0);

}

IMReceiver::~IMReceiver()
{
    NotifyQuitToWWMain();
}
void IMReceiver::NotifyQuitToWWMain()
{
    m_is_inloginsession = false;
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.imreceiver.closed", BuildinType2Param(1), SendDirectToClient);
}
void IMReceiver::NotifyReadyToWWMain()
{
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.imreceiver.ready", BuildinType2Param(1), SendDirectToClient);
    m_healthtimerid = threadpool::queue_timer_task(boost::bind(&IMReceiver::HealthCheckThreadFunc, this), 3, 1);
}
void IMReceiver::SetWWMainUniqueFlag(const std::string& unique)
{
    m_wwmain_unique = unique;
}
bool IMReceiver::OnReqQuit(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    threadpool::deletetimerbyid(m_healthtimerid);
    m_running = false;
    m_is_inloginsession = false;
    NotifyQuitToWWMain();
    ForceQuit();
    exit(0);
    return true;
}
bool IMReceiver::IsRunning()
{
    return m_running;
}

bool IMReceiver::OnLogout(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    m_is_inloginsession = false;
    m_all_group2contacts.clear();
    m_all_tagnames.clear();
    m_all_contacts.clear();
    printf("logout finished.\n");
    return true;
}

bool IMReceiver::OnIMMainError(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    std::string clientname;
    Param2CustomType(param, clientname);
    if(clientname == m_wwmain_unique)
    {
        // 旺旺主程序可能已经异常退出
        m_running = false;
        threadpool::deletetimerbyid(m_healthtimerid);
        ForceQuit();
        exit(0);
    }
    return true;
}
bool IMReceiver::OnTextMsg(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        g_log.Log(lv_warn, "receiver text message while not in login session.");
    }
    IMTextMessageVector msgvec;
    Param2CustomType(param, msgvec);
    for(size_t i = 0; i < msgvec.size(); i++)
    {
        const IMTextMessage& msg = msgvec[i];

        if(msg.bsend_)
        {
            time_t recvtime = (time_t)msg.time_;
            printf("%s: %s , #time: %s", msg.fromuid_.c_str(), 
                msg.text_.c_str(), ctime(&recvtime));
        }
        else
        {
            time_t sendtime = (time_t)msg.time_;
            printf("you said to %s: %s, #time: %s", msg.id_.c_str(), msg.text_.c_str(), ctime(&sendtime));
        }
    }
    return true;
}

bool IMReceiver::OnIMContactsReady(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        g_log.Log(lv_warn, "receiver message while not in login session.");
    }
    MsgBusParam2GroupContactInfo(param, m_all_group2contacts);
    std::map<string, ContactContainerT>::const_iterator cit = m_all_group2contacts.begin();
    while(cit != m_all_group2contacts.end())
    {
        // add group name 
        m_all_tagnames.insert(cit->first);
        m_all_contacts.insert(cit->second.begin(), cit->second.end());
        ++cit;
    }
    return true;
}

bool IMReceiver::OnIMAddContact(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        g_log.Log(lv_warn, "receiver message while not in login session.");
    }
    std::string msgdata;
    Param2CustomType(param, msgdata);
    printf("some one added you as friend.\n");
    printf("%s\n", msgdata.c_str());
    return true;
}

bool IMReceiver::OnIMSubscriptionMsg(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        g_log.Log(lv_warn, "receiver message while not in login session.");
    }
    IMSubscriptionMessage sm;
    Param2CustomType(param, sm);
    std::string substr;
    substr = sm.maintitle_ + "-" + sm.title_ +
            "  " + sm.time_ + "\n" + sm.content_ + sm.message_;
    printf("%s\n", substr.c_str());
    return true;
}

bool IMReceiver::OnIMVerifyUserUpdate(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    PostMsg("im.frontend.cmd.userverifyinfo.update", param);
    return true;
}

bool IMReceiver::OnIMNeedAuthCode(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    printf("authcode is needed by server, cmd receiver not supported.(please change to QTIMReceiver )\n");
    return true;
}

bool IMReceiver::OnIMRspExportBinMsgs(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        printf("not in login session.\n");
        return false;
    }
    if(m_exportfilepath.empty())
    {
        g_log.Log(lv_warn, "export bin message file path empty!");
        return false;
    }
    IMTextMessageVector immsgs;
    Param2CustomType(param, immsgs);
    core::XParam xp = IMTextMessage::VectorTypeToXParam(immsgs);
    xp.ToJsonFile(m_exportfilepath);
    g_log.Log(lv_debug, "export bin messages to file success:%s", m_exportfilepath.c_str());
    m_exportfilepath.clear();
    return true;
}


//bool IMReceiver::OnIMAuthCodeOK(const std::string& msgid, MsgBusParam& param, bool& is_continue)
//{
//    core::XParam info;
//    Param2CustomType(param, info);
//    std::string session;
//    info.get_Str("session", session);
//    m_all_authcodedlg.erase(session);
//    return true;
//}
//bool IMReceiver::OnIMAuthCodeFailed(const std::string& msgid, MsgBusParam& param, bool& is_continue)
//{
//    core::XParam info;
//    Param2CustomType(param, info);
//    std::string session;
//    info.get_Str("session", session);
//    emit receiveAuthCodeFailed(session);
//    return true;
//}

bool IMReceiver::OnIMLoginFailed(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    printf("login failed\n");
    m_is_inloginsession = false;
    return true;
}
bool IMReceiver::OnIMLoginOK(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    g_log.Log(lv_debug, "login success in IMReceiver.");
    m_is_inloginsession = true;
    return true;
}

string transfer_string(FileTransferNotify param)
{
    if(param.issender)
    {
        return param.filename + " to " + param.destid;
    }
    return param.filename + " from " + param.destid;
}
//
//
bool IMReceiver::OnIMFileTransferNotify(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    FileTransferNotify fileparam;
    Param2CustomType(param, fileparam);
    //g_log.Log(lv_debug, "got the transfer notify : %s in receiver.", fileparam.notifytype.c_str());
    if(fileparam.notifytype == "sendrequest")
    {
        printf("\"%s\" want to send the file: \"%s\" (size: %llu bytes) to you.\n", 
            fileparam.destid.c_str(), fileparam.filename.c_str(), fileparam.filesize);
        printf("type 'recvfile' followed by session id(%s) to accept and save this file to the path specified by the second argument.\n",
            fileparam.session.c_str());
        printf("type 'rejectfile' followed by the session id to reject receive file.\n");

        m_all_transfersession[fileparam.session] = fileparam;
    }
    else if(fileparam.notifytype == "sendfailed")
    {
        printf("send file %s to %s failed.\n", fileparam.filename.c_str(), fileparam.destid.c_str());
    }
    else if(fileparam.notifytype == "sendstart")
    {
        g_log.Log(lv_debug, "got the send start in receiver.");
        m_all_transfersession[fileparam.session] = fileparam;
    }
    else if(fileparam.notifytype == "reportevent")
    {
        std::map<string, FileTransferNotify>::iterator it = m_all_transfersession.find(fileparam.session);
        if(it != m_all_transfersession.end())
        {
            int code = fileparam.notifycode;
            switch(code)
            {
            case FILE_EVENT_CODE_FINISH:
            case FILE_EVENT_CODE_FINISH_CATHE_HAVE:
                {
                    printf("file transfer finished successfully.(%s)\n", transfer_string(it->second).c_str());
                    m_all_transfersession.erase(it);
                }
                break;
            case FILE_EVENT_CODE_ACCEPT:
                {
                    printf("the user has accept the file transfer request. (%s)\n", transfer_string(it->second).c_str());
                }
                break;
            case FILE_EVENT_CODE_REJECT:
            case FILE_EVENT_CODE_CONFIG_REFUSE:
            case FILE_EVENT_CODE_CONFIG_REFUSE_UNSAFE:
            case FILE_EVENT_CODE_CONFIG_REFUSE_ALL:
                {
                    printf("the user rejected the file transfer request. (%s)\n", transfer_string(it->second).c_str());
                    m_all_transfersession.erase(it);
                }
                break;
            case FILE_EVENT_CODE_CANCEL:
                {
                    printf("the file transfer has been cancelled. (%s)\n", transfer_string(it->second).c_str());
                    m_all_transfersession.erase(it);
                }
                break;
            case FILE_EVENT_CODE_UNKOWN_ERR:
                {
                    printf("error happened while transfering the file. (%s)\n", transfer_string(it->second).c_str());
                    m_all_transfersession.erase(it);
                }
                break;
            default:
                break;
            }
            g_log.Log(lv_debug, "got the reportevent:%d in receiver.", fileparam.notifycode);
        }
    }
    else if(fileparam.notifytype == "reporterror")
    {
        std::map<string, FileTransferNotify>::iterator it = m_all_transfersession.find(fileparam.session);
        if(it != m_all_transfersession.end())
        {
            if(fileparam.notifycode == FILE_ERR_CODE_CONNECT_FAILED)
                printf("file transfer failed, fts server failed to connect.( %s )\n", transfer_string(it->second).c_str());
            else if(fileparam.notifycode == FILE_ERR_CODE_CONNECT_ERROR)
                printf("file transfer failed, connect server error. ( %s )\n", transfer_string(it->second).c_str());
            else if(fileparam.notifycode == FILE_ERR_CODE_FILE_TOOLARGE)
                printf("file transfer failed, too large file. ( %s )\n", transfer_string(it->second).c_str());
            else if(fileparam.notifycode == FILE_ERR_CODE_INVALIDE)
                printf("file transfer failed, open file failed. ( %s )\n", transfer_string(it->second).c_str());
            else if(fileparam.notifycode == FILE_ERR_CODE_SIZEZERO)
                printf("file transfer failed, zero length not send. ( %s )\n", transfer_string(it->second).c_str());
            else if(fileparam.notifycode == FILE_ERR_CODE_NO_SPACE)
                printf("file transfer failed, disk space is not enough. ( %s )\n", transfer_string(it->second).c_str());
            else
                printf("file transfer failed. ( %s )\n", transfer_string(it->second).c_str());
            m_all_transfersession.erase(it);
            g_log.Log(lv_warn, "file transfer error. code:%llu", fileparam.notifycode);
        }
    }
    else if(fileparam.notifytype == "reportprocess")
    {
        std::map<string, FileTransferNotify>::iterator it = m_all_transfersession.find(fileparam.session);
        if(it != m_all_transfersession.end())
        {
            //printf("file transfering (%s to %s), percent:%.2f%%\n", it->second.filename.c_str(), it->second.destid.c_str(), 
            //    fileparam.notifycode/(double)it->second.filesize*100);
        }
    }
    else
    {
        g_log.Log(lv_debug, "unknown notifytype :%s", fileparam.notifytype.c_str());
    }

    return true;
}

bool IMReceiver::OnIMPicTransferFinished(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    core::XParam xp;
    Param2CustomType(param, xp);
    std::string imgname;
    std::string sendid;
    xp.get_Str("imgname", imgname);
    xp.get_Str("uid", sendid);
    printf("%s has sended you a picture:%s, saved under the ~/.AliIM/images directory.\n",
       sendid.c_str(), imgname.c_str());
    return true;
}

bool IMReceiver::OnDoNotifyOtherSide(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    FileTransferNotify fileparam;
    Param2CustomType(param, fileparam);
    string session = fileparam.session;
    if(session == "all")
    {
        std::map<string, FileTransferNotify>::iterator it = m_all_transfersession.begin();
        std::vector<string>  needdel_session;
        while(it != m_all_transfersession.end())
        {
            if(fileparam.notifytype == "accept" || fileparam.notifytype == "reject")
            {
                if(it->second.issender)
                {
                    ++it;
                    continue;
                }
            }
            it->second.notifytype = fileparam.notifytype;
            it->second.recvpath = utility::GetModulePath() + "/download/" + it->second.filename;
            it->second.notifycode = fileparam.notifycode;
            NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.filetransfer.donotifyotherside",
                CustomType2Param(it->second), SendDirectToClient);
            if(fileparam.notifytype == "reject")
            {
                needdel_session.push_back(it->first);
            }
            ++it;
        }
        for(size_t i = 0; i < needdel_session.size(); ++i)
        {
            m_all_transfersession.erase(needdel_session[i]);
        }
        return true;
    }
    std::map<string, FileTransferNotify>::iterator it = m_all_transfersession.find(session);
    if(it == m_all_transfersession.end())
    {
        printf("session id not found!\n");
        return false;
    }
    if(fileparam.notifytype == "accept" || fileparam.notifytype == "reject")
    {
        if(it->second.issender)
        {
            printf("wrong session id\n");
            return false;
        }
    }

    it->second.notifytype = fileparam.notifytype;
    if(fileparam.recvpath.empty())
    {
        it->second.recvpath = utility::GetModulePath() + "/download/" + it->second.filename;
    }
    else
    {
        it->second.recvpath = fileparam.recvpath;
    }
    it->second.notifycode = fileparam.notifycode;
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.filetransfer.donotifyotherside",
        CustomType2Param(it->second), SendDirectToClient);
    if(fileparam.notifytype == "reject")
        m_all_transfersession.erase(it);
    return true;
}

bool IMReceiver::OnDoLogin(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(m_is_inloginsession)
    {
        printf("you already in login session, please logout first.\n");
        return true;
    }
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.dologin", param, SendDirectToClient);
    return true;
}

bool IMReceiver::OnDoReLogin(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(m_is_inloginsession)
    {
        printf("you already in login session, please logout first.\n");
        return true;
    }
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.dorelogin", param, SendDirectToClient);
    return true;
}
bool IMReceiver::OnDoLogout(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        printf("you are not in login session.\n");
        return true;
    }
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.dologout", param, SendDirectToClient);
    return true;
}

bool IMReceiver::OnDoQuit(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    m_running = false;
    if(m_is_inloginsession)
        OnDoLogout(msgid, param, is_continue);
    NotifyQuitToWWMain();
    return true;
}

bool IMReceiver::OnDoVerifyUser(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(m_is_inloginsession)
    {
        core::XParam xp;
        std::string username;
        xp.get_Str("verifyname", username);
        int type = VERIFYTYPE_CHECKSENDMSG;
        xp.get_Int("verifytype", type);
        if(m_all_contacts.find(username) != m_all_contacts.end())
        {
            IMUserVerifyInfo verifyinfo;
            verifyinfo.m_uid = username;
            verifyinfo.m_verifyflag = ADDEDAUTH_NONE;
            if(type == VERIFYTYPE_ADDCONTACT)
                NetMsgBus::PostMsg("im.frontend.cmd.userverifyinfo.updateforaddcontact", CustomType2Param(verifyinfo));
            else
                NetMsgBus::PostMsg("im.frontend.cmd.userverifyinfo.update", CustomType2Param(verifyinfo));
            return true;
        }
        else
        {
            // find if nickname is match.
            ContactContainerT::const_iterator cit = m_all_contacts.begin();
            while(cit != m_all_contacts.end())
            {
                if(cit->second.m_dispName == username)
                {
                    IMUserVerifyInfo verifyinfo;
                    verifyinfo.m_uid = cit->first;
                    verifyinfo.m_verifyflag = ADDEDAUTH_NONE;
                    verifyinfo.m_dispname = username;
                    if(type == VERIFYTYPE_ADDCONTACT)
                        NetMsgBus::PostMsg("im.frontend.cmd.userverifyinfo.updateforaddcontact", CustomType2Param(verifyinfo));
                    else
                        NetMsgBus::PostMsg("im.frontend.cmd.userverifyinfo.update", CustomType2Param(verifyinfo));
                    return true;
                }
                ++cit;
            }
        }
        NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.verifyuser.req", param, SendDirectToClient);
    }
    return true;
}

bool IMReceiver::OnDoSendFile(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        printf("not in login session, please login first.\n");
        return true;
    }
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.filetransfer.dosendfile.req", param, SendDirectToClient);
    return true;
}

bool IMReceiver::OnDoExportBinMsgs(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        printf("not in login session, please login first.\n");
        return true;
    }
    if(!m_exportfilepath.empty())
    {
        g_log.Log(lv_warn, "the last export has not finished. export ignored.");
        return true;
    }
    core::XParam xp;
    Param2CustomType(param, xp);
    xp.get_Str("exportpath", m_exportfilepath);
    g_log.Log(lv_debug, "export path:%s", m_exportfilepath.c_str());
    if(m_exportfilepath.empty())
    {
        g_log.Log(lv_debug, "export path empty, ignored.");
        return true;
    }
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.doexportbinmsgs.req", param, SendDirectToClient);
    return true;
}

bool IMReceiver::OnDoSendTextMessage(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    if(!m_is_inloginsession)
    {
        printf("not in login session, please login first.\n");
        return true;
    }
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "im.frontend.sendmsg", param, SendDirectToClient);
    return true;
}

bool IMReceiver::OnDoPrintContacts(const std::string& msgid, MsgBusParam& param, bool& is_continue)
{
    std::string tagname;
    core::XParam xp;
    xp.get_Str("tagname", tagname);
    if(!m_is_inloginsession)
    {
        printf("warning:not in login session.\n");
    }
    if(tagname.empty())
    {
        // print all
    }
    else if(m_all_group2contacts.find(tagname) != m_all_group2contacts.end())
    {
        // 
    }
    else
    {
        // no such tagname
    }
    return true;
}

void IMReceiver::HealthCheckThreadFunc()
{
    NetMsgBus::NetMsgBusSendMsg(m_wwmain_unique, "netmsgbus.client.immain.healthcheck", BuildinType2Param(1), SendDirectToClient);
}

